// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-10-7

#include "stdafx.h"
#include ".\trayicon.h"


int AFXAPI AfxLoadString(UINT nID, LPSTR lpszBuf, UINT nMaxBuf);

IMPLEMENT_DYNAMIC(CJoyTrayIcon, CCmdTarget) 

//##ModelId=44C4B6020213
CJoyTrayIcon::CJoyTrayIcon(UINT uID)
{
    // Initialize NOTIFYICONDATA 
    memset(&m_nid, 0 , sizeof(m_nid)); 
    m_nid.cbSize = sizeof(m_nid);
    m_nid.uID = uID; // never changes after construction 

    // Use resource string as tip if there is one 
    AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip)); 
}

//##ModelId=44C4B6020215
CJoyTrayIcon::~CJoyTrayIcon(void)
{
    // remove icon from system tray 
    SetIcon(0);
}

//##ModelId=44C4B6020222
void CJoyTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg) 
{ 
    ASSERT(pNotifyWnd != NULL && ::IsWindow(pNotifyWnd->GetSafeHwnd())); 
    ASSERT(uCbMsg ==0 || uCbMsg>=WM_USER); 

    m_nid.hWnd = pNotifyWnd->GetSafeHwnd(); 
    m_nid.uCallbackMessage = uCbMsg; 
} 

//##ModelId=44C4B6020225
BOOL CJoyTrayIcon::SetIcon(UINT uID)
{ 
    HICON hicon=NULL; 
    if (uID)
    {
        AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip)); 
        hicon = AfxGetApp()->LoadIcon(uID); 
    } 
    return SetIcon(hicon, NULL); 
} 

//##ModelId=44C4B6020227
BOOL CJoyTrayIcon::SetIcon(HICON hicon, LPCSTR lpTip) 
{ 
    UINT msg;
    m_nid.uFlags = 0;

    // Set the icon
    if (hicon)
    {
        // Add or replace icon in system tray 
        msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD; 
        m_nid.hIcon = hicon; 
        m_nid.uFlags |= NIF_ICON; 
    }
    else
    {
        // remove icon from tray 
        if (m_nid.hIcon == NULL) 
        {
            return TRUE; // already deleted 
        }
        msg = NIM_DELETE; 
    } 

    // Use the tip, if any 
    if (lpTip) 
    {
        strncpy(m_nid.szTip, lpTip, sizeof(m_nid.szTip)); 
    }

    if (m_nid.szTip[0]) 
    {
        m_nid.uFlags |= NIF_TIP; 
    }

    // Use callback if any 
    if (m_nid.uCallbackMessage && m_nid.hWnd) 
    {
        m_nid.uFlags |= NIF_MESSAGE; 
    }

    // Do it 
    BOOL bRet = Shell_NotifyIcon(msg, &m_nid); 

    if (msg == NIM_DELETE || !bRet) 
    {
        m_nid.hIcon = NULL; // failed 
    }

    return bRet; 

} 

//##ModelId=44C4B6020218
LRESULT CJoyTrayIcon::OnTrayNotification(WPARAM wID, LPARAM lEvent) 

{ 
    if (wID!=m_nid.uID || 
        (lEvent!=WM_RBUTTONUP && lEvent!=WM_LBUTTONDBLCLK)) 
    {
        return 0; 
    }

    CMenu menu; 
    if (!menu.LoadMenu(m_nid.uID))
    {
        return 0; 
    }
    
    CMenu* pSubMenu = menu.GetSubMenu(0); 
   
    if (!pSubMenu) 
    {
        return 0; 
    }

    if (lEvent == WM_RBUTTONUP)
    { 
        // Make first menu item the default (bold font) 
       // ::SetMenuDefaultItem(pSubMenu->m_hMenu, 4, TRUE); 

        // Display the menu at the current mouse location. Theres a 
        //"bug" (Microsoft calls it a feature) in Windows 95 that requires 
        //calling SetForegroundWindow. To find out more, search for Q135788 in 

        CPoint mouse; 
        GetCursorPos(&mouse); 
        ::SetForegroundWindow(m_nid.hWnd); 
            ::TrackPopupMenu(pSubMenu->m_hMenu,
            0, mouse.x, mouse.y, 0, m_nid.hWnd, NULL);
    }
    else
    {
        // double click: execute three menu item 
		
        ::SendMessage(m_nid.hWnd,
            WM_COMMAND, pSubMenu->GetMenuItemID(4), 0);
    }

    return 1; // handled 
} 
